package no.ntnu.fp.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class DayChooser extends JPanel implements ActionListener {
	
	private static final long serialVersionUID = 1L;
	private Locale locale;
	protected JButton[] days, weeks;
	protected JButton selectedDay;
	protected JPanel weekPanel, dayPanel;
	protected int day, maxDayCharacters;
	protected String[] dayName;
	protected Calendar calendar, today;
	protected Date minDate, maxDate, defaultMinDate, defaultMaxDate;
	protected JLabel[] dayNameLabels;
	
	public DayChooser() {
		setName("JDayChooser");
		locale = Locale.getDefault();
		days = new JButton[42];
		dayNameLabels = new JLabel[7];
		selectedDay = null;
		calendar = Calendar.getInstance(locale);
		today = (Calendar)calendar.clone();
		setLayout(new BorderLayout());
		
		drawDayNames();
		dayPanel = new JPanel();
    	dayPanel.setLayout(new GridLayout(7, 7));
    	dayPanel.setPreferredSize(new Dimension(300, 150));
    	
    	for (int i = 0; i < 49; i++) {
			if ( i < 7 ) {
				dayPanel.add(dayNameLabels[i]);
			} else {
				int index = i-7;
				days[index] = new JButton("0");
    			days[index].addActionListener(this);
    			days[index].setMargin(new Insets(0, 0, 0, 0));
    			days[index].setFocusCycleRoot(false);
    			dayPanel.add(days[index]);
    			System.out.println("Added: jbutton with index: " + index);
			}
		}
    	
    	Calendar tempCalendar = Calendar.getInstance();
    	tempCalendar.set(1, 0, 1, 1, 1);
    	defaultMinDate = (Date)tempCalendar.getTime();
    	minDate = defaultMinDate;
    	tempCalendar.set(9999, 0, 1, 1, 1);
    	defaultMaxDate = (Date)tempCalendar.getTime();
    	maxDate = defaultMaxDate;
    	init();
    	setDay(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
    	add(dayPanel,BorderLayout.WEST);
    	updateUI();
	}
	
	private void init() {
		drawDays();
	}	
	
	private void drawDays() {
		Calendar tmpCalendar = (Calendar)calendar.clone();
		tmpCalendar.set(Calendar.HOUR_OF_DAY, 0);
		tmpCalendar.set(Calendar.MINUTE, 0);
		tmpCalendar.set(Calendar.SECOND, 0);
		tmpCalendar.set(Calendar.MILLISECOND, 0);
		
		Calendar minCal = Calendar.getInstance();
		minCal.set(Calendar.HOUR_OF_DAY, 0);
		minCal.set(Calendar.MINUTE, 0);
		minCal.set(Calendar.SECOND, 0);
		minCal.set(Calendar.MILLISECOND, 0);
		
		Calendar maxCal = Calendar.getInstance();
		maxCal.set(Calendar.HOUR_OF_DAY, 0);
		maxCal.set(Calendar.MINUTE, 0);
		maxCal.set(Calendar.SECOND, 0);
		maxCal.set(Calendar.MILLISECOND, 0);
		
		int firstDayOfWeek = tmpCalendar.getFirstDayOfWeek();
		tmpCalendar.set(Calendar.DAY_OF_MONTH, 1);
		int firstDay = tmpCalendar.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek;
		if (firstDay < 0) {
			firstDay += 7;
		}
		int i;
		for (i = 0; i < firstDay; i++) {
			days[i].setVisible(false);
			days[i].setText("");
		}
		tmpCalendar.add(Calendar.MONTH, 1);
		Date firstDayInNextMonth = tmpCalendar.getTime();
		tmpCalendar.add(Calendar.MONTH, -1);
		Date day = tmpCalendar.getTime();
		int n = 0;
		int index = i + n;
		Color foregroundColor = getForeground();
		while (day.before(firstDayInNextMonth)) {
			index = i + n;
			days[index].setText(Integer.toString(n + 1));
			days[index].setVisible(true);

			if ((tmpCalendar.get(Calendar.DAY_OF_YEAR) == today
					.get(Calendar.DAY_OF_YEAR))
					&& (tmpCalendar.get(Calendar.YEAR) == today
							.get(Calendar.YEAR))) {
				days[index].setForeground(new Color(100,200,100));
			} else {
				days[index].setForeground(foregroundColor);
			}

			if ((n + 1) == this.day) {
				days[index].setBackground(new Color(200,20,30));
				selectedDay = days[index];
			} else {
				days[index].setBackground(new Color(220,120,120));
			}

			if (tmpCalendar.before(minCal) || tmpCalendar.after(maxCal)) {
				days[index].setEnabled(true);
			} else {
				days[index].setEnabled(false);
			}
			
			n++;
			tmpCalendar.add(Calendar.DATE, 1);
			day = tmpCalendar.getTime();
		}
		for (int k = index + 1; k < days.length; k++) {
			days[k].setVisible(false);
			days[k].setText("");
		}
	}

	private void drawDayNames() {
		int firstDayOfWeek = calendar.getFirstDayOfWeek();
		DateFormatSymbols dateSymbols = new DateFormatSymbols(locale);
		dayName = dateSymbols.getShortWeekdays();
		int day = firstDayOfWeek;
		for (int i = 0 ; i < 7 ; i++) {
			if (maxDayCharacters > 0 && maxDayCharacters < 5) {
				if (dayName[day].length() >= maxDayCharacters) {
					dayName[day] = dayName[day].substring(0, maxDayCharacters);
				}
			}
			dayNameLabels[i] = new JLabel(dayName[day]);
			if (day<7) {
				day++;
		    } else {
		    	day-=6;
		    }
		}
	}
	
	public void setDay(int d) {
		if (d < 1) {
			d = 1;
		}
		Calendar tmpCalendar = (Calendar)calendar.clone();
		tmpCalendar.set(Calendar.DAY_OF_MONTH, 1);
		tmpCalendar.add(Calendar.MONTH, 1);
		tmpCalendar.add(Calendar.DATE, -1);
		int maxDayinMonths = tmpCalendar.get(Calendar.DATE);
		if (d > maxDayinMonths) {
			d = maxDayinMonths;
		}
		int oldDay = day;
		day = d;
		firePropertyChange("day", oldDay, day);
	}
	
	public void setMonth(int month) {
//		System.out.println("The DayChooser class is called");
		calendar.set(Calendar.MONTH, month);
//		System.out.println("This is " + calendar.MONTH);
		int maxDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
		int adjustedDay = day;
		if (day > maxDays) {
			adjustedDay = day;
			setDay(adjustedDay);
//			System.out.println("This is the day in the daychooser class" + adjustedDay);
		}
		drawDays();
	}
	
	public void setYear(int year) {
		calendar.set(Calendar.YEAR, year);
		drawDays();
	}

	public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
		for (short i = 0; i < days.length; i++) {
			if (days[i] != null) {
				days[i].setEnabled(enabled);
			}
		}
		for (short i = 0; i < weeks.length; i++) {
			if (weeks[i] != null) {
				weeks[i].setEnabled(enabled);
			}
		}
	}

	class DayActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == null) {
				System.out.println("null");
			} else {
				JButton button = (JButton)e.getSource();
				day = Integer.valueOf(button.getText());
				System.out.println(day);
			}
	    }
    }
        
	public int getDay(){
		return day;
	}
	
	public void actionPerformed(ActionEvent e) {
		JButton button = (JButton) e.getSource();
		String buttonText = button.getText();
		int day = new Integer(buttonText).intValue();
		setDay(day);
	}
	
	public static void main(String args[]){
		JFrame jframe = new JFrame();
		jframe.add(new DayChooser());
		jframe.pack();
		jframe.setVisible(true);
	}

}
